package com.tiancikeji.zaoke.app.ajax.order;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import com.tiancikeji.zaoke.app.biz.FoodBiz;
import com.tiancikeji.zaoke.app.biz.OrderBiz;
import com.tiancikeji.zaoke.app.biz.UserBiz;
import com.tiancikeji.zaoke.app.biz.ZoneBiz;
import com.tiancikeji.zaoke.app.common.dispatch.AjaxClass;
import com.tiancikeji.zaoke.app.common.dispatch.AjaxMethod;
import com.tiancikeji.zaoke.app.constants.ErrorCodeConstants;
import com.zaoke.web.bo.food.Food;
import com.zaoke.web.bo.food.FoodNutrition;
import com.zaoke.web.bo.food.FoodPrice;
import com.zaoke.web.bo.food.FoodTag;
import com.zaoke.web.bo.order.Order;
import com.zaoke.web.bo.order.OrderFood;
import com.zaoke.web.bo.user.User;
import com.zaoke.web.bo.zone.Zone;

@AjaxClass
public class OrderAjax {
	
	private UserBiz userBiz;
	
	private ZoneBiz zoneBiz;
	
	private OrderBiz orderBiz;
	
	private FoodBiz foodBiz;
	
	@AjaxMethod(path = "GET/orders")
	public Map<Object, Object> getActiveOrder(Map<String, String> params){
		Map<Object, Object> result = new HashMap<Object, Object>();
		result.put("status", ErrorCodeConstants.STATUS_PARAM_ERROR);
		result.put("msg", ErrorCodeConstants.ERROR_MSG_MAP.get(ErrorCodeConstants.STATUS_PARAM_ERROR));
		
		if(params != null && params.containsKey("zoneid")){
			long zoneid = getLong(params.get("zoneid"));
			
			if(zoneid > 0){
				Zone zone = zoneBiz.getZoneById(zoneid);
				if(zone != null){
					List<Order> orders = orderBiz.getActiveOrdersByZoneId(zoneid);
					if(orders != null && orders.size() > 0){
						Set<Long> foodIds = new HashSet<Long>();
						Set<Long> userIds = new HashSet<Long>();
						for(Order order : orders)
							if(order != null && order.getOrderFood() != null && order.getOrderFood().size() > 0){
								userIds.add(order.getUserid());
								for(OrderFood food : order.getOrderFood())
									if(food != null && food.getFoodid() > 0)
										foodIds.add(food.getFoodid());
							}
						
						if(foodIds.size() > 0){
							Map<Long, Food> foods = new HashMap<Long, Food>();
							for(Long fId : foodIds)
								foods.put(fId, foodBiz.getFoodInfo(fId));
							
							Map<Long, User> users = new HashMap<Long, User>();
							if(userIds.size() > 0){
								users = userBiz.getUsers(userIds);
							}
					
							if(foods.size() > 0)
								genOrder4View(orders, result, foods, users);
						}
					}
					genZone4View(zone, result);
					result.put("status", ErrorCodeConstants.STATUS_OK);
					result.remove("msg");
				}
			}
		}
			
		return result;
	}
	
	private void genZone4View(Zone zone, Map<Object, Object> result) {
		if(zone != null){
			result.put("pick_loc_name", zone.getName());
			result.put("pick_loc_id", zone.getId());
			result.put("pick_start_time", zone.getPickStartTime());
			result.put("pick_end_time", zone.getPickEndTime());
		}
	}

	private void genOrder4View(List<Order> orders, Map<Object, Object> result, Map<Long, Food> foods, Map<Long, User> users) {
		if(orders != null && orders.size() > 0){
			List<Map<Object, Object>> os = new ArrayList<Map<Object,Object>>();
			for(Order order : orders){
				if(order != null && order.getOrderFood() != null && order.getOrderFood().size() > 0){
					if(users == null || !users.containsKey(order.getUserid()))
						continue;
					
					User user = users.get(order.getUserid());
					if(user == null || user.getState() == User.STATE_LOCK)
						continue;
					
					Map<Object, Object> ostmp = new HashMap<Object, Object>();
					ostmp.put("orderid", order.getOrderid());
					ostmp.put("order_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(order.getOrdertime()));
					ostmp.put("sale_price", order.getPrice());
					ostmp.put("paymode", order.getPayway());
					ostmp.put("status", order.getState());
					ostmp.put("pick_date", order.getBooktime());
					
					ostmp.put("userid", user.getUserId());
					ostmp.put("username", user.getUserName());
					ostmp.put("cardid", user.getCardId());
					ostmp.put("phone", user.getCellPhone());
					ostmp.put("state", user.getState());
					
					if(order.getOrderFood().size() == 2){
						FoodPrice price = foodBiz.getFoodPrice( foods.get(order.getOrderFood().get(0).getFoodid()),  foods.get(order.getOrderFood().get(1).getFoodid()));
						if(price != null && (price.getSalePrice() > 0 || price.getComboPrice() > 0 || price.getPromotionPrice() > 0))
							genPriceForView(price, ostmp);
					}
					
					for(OrderFood food : order.getOrderFood())
						if(foods.containsKey(food.getFoodid())){
							Map<Object, Object> desc = new HashMap<Object, Object>();
							Food tmp = foods.get(food.getFoodid());
							if(tmp != null){
								genFood4View(tmp, desc);
								ostmp.put(tmp.getType(), desc);
							}
						}
					
					os.add(ostmp);
				}
			}
			
			if(os != null && os.size() > 0)
				result.put("orders", os);
		}
	}

	private void genPriceForView(FoodPrice price, Map<Object, Object> result) {
		if(price != null){
			if(price.getSalePrice() > 0)
				result.put("sale_price", price.getSalePrice());
			if(price.getComboPrice() > 0)
				result.put("combo_price", price.getComboPrice());
			if(price.getPromotionPrice() > 0)
				result.put("promotion_price", price.getPromotionPrice());
		}
	}
	
	private void genFood4View(Food food, Map<Object, Object> result) {
		if(food != null && food.getId() > 0 && StringUtils.isNotBlank(food.getName())){
			result.put("id", food.getId());
			result.put("name", food.getName());
			result.put("desc", food.getDesc());
			result.put("sale_price", food.getSalePrice());
			
			if(food.getTags() != null && food.getTags().size() > 0){
				List<String> tags = new ArrayList<String>();
				for(FoodTag tag : food.getTags())
					tags.add(tag.getTag());
				result.put("tags", tags);
			}
			
			if(food.getNutritions() != null && food.getNutritions().size() > 0){
				Map<String, String> nutritions = new HashMap<String, String>();
				for(FoodNutrition nutrition : food.getNutritions())
					if(StringUtils.isNotBlank(nutrition.getValue()) && nutrition.getNutrition() != null && StringUtils.isNotBlank(nutrition.getNutrition().getName()))
						nutritions.put(nutrition.getNutrition().getName(), nutrition.getValue());
				result.put("nutrition", nutritions);
			}
			
			if(food.getImage() != null)
				result.put("image_url", food.getImage().getUrl());
			
			if(food.getPromotion() != null)
				result.put("promotion", "1");
			else
				result.put("promotion", "0");
		}
	}

	@AjaxMethod(path = "order/consume")
	public Map<Object, Object> consumeOrder(Map<String, String> params){
		Map<Object, Object> result = new HashMap<Object, Object>();
		result.put("status", ErrorCodeConstants.STATUS_PARAM_ERROR);
		result.put("msg", ErrorCodeConstants.ERROR_MSG_MAP.get(ErrorCodeConstants.STATUS_PARAM_ERROR));
		
		if(params != null && params.containsKey("orderids")){
			String orderids = params.get("orderids");
			
			Set<Long> orderIds = new HashSet<Long>();
			if(StringUtils.isNotBlank(orderids))
				for(String orderid : StringUtils.split(orderids, "|"))
					if(NumberUtils.isNumber(orderid))
						orderIds.add(NumberUtils.toLong(orderid));
			Set<Long> failures = new HashSet<Long>();
			failures.addAll(orderIds);
			if(orderIds.size() > 0)
				for(Long orderid : orderIds){
					try{
						Order order = orderBiz.getOrderById(orderid);
						if(order != null && order.getOrderid() == orderid.longValue()){
							if(orderBiz.consumeOrder(order)){
								failures.remove(orderid);
							}
						}
					} catch(Throwable t){
						t.printStackTrace();
						failures.add(orderid);
					}
				}
			if(failures.size() > 0){
				result.put("status", ErrorCodeConstants.STATUS_ERROR);
				result.put("msg", StringUtils.join(failures, "|"));
			} else{
				result.put("status", ErrorCodeConstants.STATUS_OK);
				result.remove("msg");
			}
		}
		
		System.out.println("consume <" + params.get("orderids") + "> failures <" + result.get("msg") + ">");
		
		return result;
	}

	public long getLong(Object obj) {
		long data = 0l;
		try{
			if(obj != null)
				data = Long.parseLong(obj.toString());
		} catch(Throwable t){
			// left blank;
		}
		return data;
	}

	public UserBiz getUserBiz() {
		return userBiz;
	}

	public void setUserBiz(UserBiz userBiz) {
		this.userBiz = userBiz;
	}

	public ZoneBiz getZoneBiz() {
		return zoneBiz;
	}

	public void setZoneBiz(ZoneBiz zoneBiz) {
		this.zoneBiz = zoneBiz;
	}

	public OrderBiz getOrderBiz() {
		return orderBiz;
	}

	public void setOrderBiz(OrderBiz orderBiz) {
		this.orderBiz = orderBiz;
	}

	public FoodBiz getFoodBiz() {
		return foodBiz;
	}

	public void setFoodBiz(FoodBiz foodBiz) {
		this.foodBiz = foodBiz;
	}
}
